package com.slightech.marvin.api.doc.parser;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author willardwang
 * @description
 * @date 2019/08/05
 */
public class FieldMapper {
    private static Map<String, DocField> docFieldMap = new HashMap<>();


    private static final List<String> basicTypes = Arrays.asList("java.lang.Integer", "int", "java.lang.String",
            "string", "java.lang.Boolean", "boolean", "long", "java.lang.Long"
    );

    private static final List<String> basicArrayTypes = Arrays.asList("List<String>", "list<string>", "List<Integer>", "list<int>", "java.util.List<java.lang.String>",
            "java.util.List<java.lang.Integer>", "java.util.List<java.lang.Long>"
    );

    static {
        DocField docFieldInteger = new DocField();
        docFieldInteger.setRealType("java.lang.Integer");
        docFieldInteger.setShowType("int");
        docFieldInteger.setExampleValue(1);
        docFieldMap.put(docFieldInteger.getRealType(), docFieldInteger);

        DocField docFieldInt = new DocField();
        docFieldInt.setRealType("int");
        docFieldInt.setShowType("int");
        docFieldInt.setExampleValue(1);
        docFieldMap.put(docFieldInt.getRealType(), docFieldInt);

        DocField docFieldString = new DocField();
        docFieldString.setRealType("java.lang.String");
        docFieldString.setShowType("string");
        docFieldString.setExampleValue("string");
        docFieldMap.put(docFieldString.getRealType(), docFieldString);

        DocField docFieldStringB = new DocField();
        docFieldStringB.setRealType("string");
        docFieldStringB.setShowType("string");
        docFieldStringB.setExampleValue("string");
        docFieldMap.put(docFieldStringB.getRealType(), docFieldStringB);

        DocField docFieldBoolean = new DocField();
        docFieldBoolean.setRealType("java.lang.Boolean");
        docFieldBoolean.setShowType("boolean");
        docFieldBoolean.setExampleValue(true);
        docFieldMap.put(docFieldBoolean.getRealType(), docFieldBoolean);

        DocField docFieldBooleanB = new DocField();
        docFieldBooleanB.setRealType("boolean");
        docFieldBooleanB.setShowType("boolean");
        docFieldBooleanB.setExampleValue(true);
        docFieldMap.put(docFieldBooleanB.getRealType(), docFieldBooleanB);


        DocField docFieldLong1 = new DocField();
        docFieldLong1.setRealType("java.lang.Long");
        docFieldLong1.setShowType("int");
        docFieldLong1.setExampleValue(1);
        docFieldMap.put(docFieldLong1.getRealType(), docFieldLong1);

        DocField docFieldLong = new DocField();
        docFieldLong.setRealType("long");
        docFieldLong.setShowType("int");
        docFieldLong.setExampleValue(1);
        docFieldMap.put(docFieldLong.getRealType(), docFieldLong);


        DocField docFieldListOfString = new DocField();
        docFieldListOfString.setRealType("java.util.List<java.lang.String>");
        docFieldListOfString.setShowType("json array string");
        List<String> stringList = Arrays.asList("string", "string");
        docFieldListOfString.setExampleValue(stringList);
        docFieldMap.put(docFieldListOfString.getRealType(), docFieldListOfString);
        docFieldMap.put("List<String>", docFieldListOfString);
        docFieldMap.put("list<string>", docFieldListOfString);

        DocField docFieldListOfInteger = new DocField();
        docFieldListOfInteger.setRealType("java.util.List<java.lang.Integer>");
        docFieldListOfInteger.setShowType("json array int");
        List<Integer> integerList = Arrays.asList(1, 2, 3);
        docFieldListOfInteger.setExampleValue(integerList);
        docFieldMap.put(docFieldListOfInteger.getRealType(), docFieldListOfInteger);



        DocField docFieldListOfLong = new DocField();
        docFieldListOfLong.setRealType("java.util.List<java.lang.Long>");
        docFieldListOfLong.setShowType("json array int");
        List<Integer> longList = Arrays.asList(1, 2, 3);
        docFieldListOfLong.setExampleValue(longList);
        docFieldMap.put(docFieldListOfLong.getRealType(), docFieldListOfLong);


        docFieldMap.put("List<Integer>", docFieldListOfInteger);
        docFieldMap.put("list<int>", docFieldListOfInteger);
        docFieldMap.put("List<Long>", docFieldListOfLong);

        DocField docFieldFile = new DocField();
        docFieldFile.setRealType("file");
        docFieldFile.setShowType("file");
        docFieldFile.setExampleValue("null");
        docFieldMap.put(docFieldFile.getRealType(), docFieldFile);

        DocField docFieldFileOfMultipart = new DocField();
        docFieldFileOfMultipart.setRealType("org.springframework.web.multipart.MultipartFile");
        docFieldFileOfMultipart.setShowType("file");
        docFieldFileOfMultipart.setExampleValue("null");
        docFieldMap.put(docFieldFileOfMultipart.getRealType(), docFieldFileOfMultipart);
    }

    public static boolean isBasicType(String typeName) {
        return basicTypes.stream().anyMatch(tname -> tname.equals(typeName));
    }

    public static boolean isBasicArray(String typeName) {
        return basicArrayTypes.stream().anyMatch(tname -> tname.equals(typeName));
    }

    public static DocField getDocField(String typeName) {
        return docFieldMap.get(typeName);
    }

    /**
     * @param typeName
     * @param value
     * @return
     */
    public static Object getObjectValue(String typeName, String value) {
        switch (typeName) {
            case "java.lang.Integer":
            case "List<Integer>":
            case "list<int>":
            case "int":
            case "java.lang.Long":
            case "long":
                return Integer.valueOf(value);
            case "java.lang.String":
                return value;
            case "string":
            case "List<String>":
            case "list<string>":
                return value;
            case "java.lang.Boolean":
                return Boolean.getBoolean(value);
            case "boolean":
                return Boolean.getBoolean(value);
        }
        return "unkonw";
    }
}
